package com.atguigu.test6;

/**
 * @author 路飞
 * @date 2024/3/29 20:42
 * @description 编程实现单向链表，并实现单向链表的反转。
 * 比如一个链表是这样的：1->2->3->4->5，
 * 通过反转后成为5->4->3->2->1，
 * 注：即实现单向链表类，
 * 在该类中提供一个单向链表的反转方法reverse，
 * 请写出完整代码
 */
public class Test5 {
    public static void main(String[] args) {
        MyLinkedList<Integer> list = new MyLinkedList<>();
        list.add(3);
        list.add(34);
        list.add(5);
        list.add(5435634);
        list.add(56);
        list.add(2);
        list.add(354);
        System.out.println("原始的顺序为：");
        System.out.println(list);
        list.reverse();
        System.out.println("反转之后的顺序为：");
        System.out.println(list);
    }
}

class MyLinkedList<T> {
    private Node<T> first;

    private Node<T> last;

    private int size;

    class Node<T> {
        T t;
        Node<T> next;

        public Node(T t, Node next) {
            this.t = t;
            this.next = next;
        }
    }

    public void add(T t) {
        if (first == null) {
            Node<T> node = new Node(t, null);
            first = node;
            last = node;
        } else {
            Node<T> node = new Node(t, null);
            Node<T> tempLast = last;
            last = node;
            tempLast.next = node;
        }
        size++;
    }

    public int size() {
        return size;
    }

    /**
     * @description 元素反转
     */
    public void reverse() {
        // 先根据第一个元素，找到所有元素，并添加到一个数组里面，
        Node<T>[] nodes = new Node[size];
        int index = 0;
        Node<T> tempNode = first;
        while (tempNode.next != null) {
            nodes[index++] = tempNode;
            tempNode = tempNode.next;
        }
        nodes[index++] = last;

        // 重新修改首尾元素
        first = nodes[size - 1];
        last = nodes[0];
        // 并且让最后一个元素的下一个元素为null 否则会出现单向链表死循环
        last.next = null;
        // 遍历数组，修改当前元素的下一个元素的地址值
        for (int i = size - 1; i > 0; i--) {
            nodes[i].next = nodes[i - 1];
        }
    }

    public String toString() {
        StringBuilder sb = new StringBuilder("[");
        // 如果没有一个元素，那么打印一个空的内容
        if (first == null) {
            sb.append("]");
            return sb.toString();
        }
        // 如果只有一个元素，那么就打印出当前元素的内容
        if (first == last) {
            sb.append(first.t + "]");
            return sb.toString();
        }

        // 如果有多个元素，那么就把所有元素内容都打印出来
        Node<T> tempNode = first;
        while (tempNode.next != null) {
            if (tempNode != last) {
                sb.append(tempNode.t + ", ");
            } else {
                sb.append(tempNode.t);
            }
            tempNode = tempNode.next;
        }
        sb.append(last.t + "]");

        return sb.toString();
    }
}
